package com.codedef.library.util;

import okhttp3.*;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;


public class Reserver {

    private static final String WX_UA = "Mozilla/5.0 (Linux; Android 10; MI 5; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045409 Mobile Safari/537.36 MMWEBID/5685 MicroMessenger/7.0.19.1760(0x27001353) Process/tools WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64";


    //保存登录后的Cookie
    Map<String, List<Cookie>> cookieStore = new ConcurrentHashMap<>();

    OkHttpClient okHttpClient;

    public Reserver() {
        okHttpClient = this.getOkHttpClient();
    }

    public boolean login(String username, String password) {
        cookieStore.clear();

        RequestBody formBody = new FormBody.Builder()
                .add("__VIEWSTATE", "/wEPDwULLTE0MTcxNzMyMjZkZJoL/NVYL0T+r5y3cXpfEFEzXz+dxNVtb7TlDKf8jIxz")
                .add("__VIEWSTATEGENERATOR", "F2D227C8")
                .add("__EVENTVALIDATION", "/wEWBQKV1czoDALyj/OQAgKXtYSMCgKM54rGBgKj48j5D1AZa5C6Zak6btNjhoHWy1AzD9qoyayyu5qGeLnFyXKG")
                .add("Button1", "登 录")
                .add("hfurl", "")
                .add("tbUserName", username)
                .add("tbPassWord", password)
                .build();
        Request request = new Request.Builder()
                .url("http://libzwxt.ahnu.edu.cn/SeatWx/login.aspx")
                .post(formBody)
                .build();
        Call call = okHttpClient.newCall(request);
        String result = null;
        try {
            Response response = call.execute();
            result = response.body().string();

        } catch (IOException e) {
            e.printStackTrace();
        }

        if(result != null && result.contains("个人中心"))
            return true;
        return false;
    }

    public boolean reserve(String atDate, String sid, String st, String et) {

        String data = String.format("{\"atDate\": \"%s\", \"sid\": \"%s\", \"st\": \"%s\", \"et\": \"%s\"}", atDate, sid, st, et);

        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), data);

        Request request = new Request.Builder()
                .url("http://libzwxt.ahnu.edu.cn/SeatWx/ajaxpro/SeatManage.Seat,SeatManage.ashx")
                .header("Host", "libzwxt.ahnu.edu.cn")
                .header("Origin", "http://libzwxt.ahnu.edu.cn")
                .header("Referer", "http://libzwxt.ahnu.edu.cn/SeatWx/Seat.aspx?fid=3&sid=1438")
                .header("User-Agent", WX_UA)
                .header("X-AjaxPro-Method", "AddOrder")
                .post(requestBody)
                .build();
        Call call = okHttpClient.newCall(request);
        String result = null;
        Response response = null;
        int n = 5;

        try {
            response = call.execute();
            result = response.body().string();
            System.out.println("预约：" + result);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(response != null) response.close();
        }

        // 极卡无比情况の 特判 开始
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");// 设置日期格式
        Date now = null, beginTime = null, endTime = null;
        try {
            now = df.parse(df.format(new Date()));
            beginTime = df.parse("00:00");
            endTime = df.parse("00:15");
        } catch (Exception e) {
            e.printStackTrace();
        }
        boolean goubixitong = DateUtil.belongCalendar(now, beginTime, endTime);
        if(goubixitong && result == null) return true;
        // 特判 结束

        if (result == null) {
            //网络错误
            System.out.println("Reserver预约：网络错误 result == null");
            return false;
        } else if(result.contains("成功")) {
            //预约成功
            System.out.println("Reserver预约：预约成功");
            return true;
        } else if(result.contains("二次预约时间间隔太短")) {
            //本账号该时间已预约
            System.out.println("Reserver预约：本账号该时间已预约");
            return false;
        } else if(result.contains("跟别人有重复部分")) {
            System.out.println("Reserver预约：跟别人有重复部分");
            return false;
        } else {
            System.out.println("Reserver预约：其他异常");
            return false;
        }

    }

    public boolean cancelOrder() {
        String orderPage = queryOrderPage();
        int index = orderPage.indexOf("Del(\\\"");
        if(index == -1) return false;
        index += 6;
        String orderId = orderPage.substring(index, index + 7);

        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{\"id\": " + orderId + "}");

        Request request = new Request.Builder()
                .url("http://libzwxt.ahnu.edu.cn/SeatWx/ajaxpro/SeatManage.Record,SeatManage.ashx")
                .header("Host", "libzwxt.ahnu.edu.cn")
                .header("Origin", "http://libzwxt.ahnu.edu.cn")
                .header("Referer", "http://libzwxt.ahnu.edu.cn/seatwx/Record.aspx")
                .header("User-Agent", WX_UA)
                .header("X-AjaxPro-Method", "DelOrder")
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        String result = null;
        Response response =null;
        try {
            response = call.execute();
            result = response.body().string();

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(response != null) response.close();
        }

        if(result.contains("ok"))
            return true;

        return false;
    }

    public String queryOrderPage() {

        // 查询预约列表
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{\n" +
                "\t\"st\": \"\",\n" +
                "\t\"et\": \"\"\n" +
                "}");

        Request request = new Request.Builder()
                .url("http://libzwxt.ahnu.edu.cn/SeatWx/ajaxpro/SeatManage.Record,SeatManage.ashx")
                .header("Host", "libzwxt.ahnu.edu.cn")
                .header("Origin", "http://libzwxt.ahnu.edu.cn")
                .header("Referer", "http://libzwxt.ahnu.edu.cn/seatwx/Record.aspx")
                .header("User-Agent", WX_UA)
                .header("X-AjaxPro-Method", "GetOrderList")
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        String result = null;
        Response response = null;
        try {
            response = call.execute();
            result = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(response != null) response.close();
        }
        return result;
    }

    /**
     * 查询一个座位在某个时间是否被预约
     */
    public boolean querySeat(String sid, String date, String startTime, String endTime) {
        // ************************ 请求数据 ************************

        // 查询座位的预约信息
        RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), "{\n" +
                "\t\"sid\": \""+ sid +"\",\n" +
                "\t\"atdate\": \"" + date + "\"\n" +
                "}");

        Request request = new Request.Builder()
                .url("http://libzwxt.ahnu.edu.cn/SeatWx/ajaxpro/SeatManage.Seat,SeatManage.ashx")
                .header("Host", "libzwxt.ahnu.edu.cn")
                .header("Origin", "http://libzwxt.ahnu.edu.cn")
                .header("Referer", "http://libzwxt.ahnu.edu.cn/SeatWx/Seat.aspx?fid=9&sid=2507")
                .header("User-Agent", WX_UA)
                .header("X-AjaxPro-Method", "GetSetInfo")
                .post(requestBody)
                .build();

        Call call = okHttpClient.newCall(request);
        String result = null;
        Response response = null;
        try {
            response = call.execute();
            result = response.body().string();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(response != null) response.close();
        }

        // ************************ 解析数据 ************************
        String html = result.substring(1, result.length() - 4);

        Document doc = Jsoup.parseBodyFragment(html);
        Element content = doc.body();
        Elements liList = content.children();

        // 时间转化为int
        int startHour = Integer.parseInt(startTime.substring(0, 2));
        int startMinute = Integer.parseInt(startTime.substring(3, 5));
        int endHour = Integer.parseInt(endTime.substring(0, 2));
        int endMinute = Integer.parseInt(endTime.substring(3, 5));

        // 将 21:00 转化为 20:59
        if (endMinute == 0) {
            endHour -= 1;
            endMinute = 59;
        }

        // 计算时间差
        int startHourIndex = startHour - 8;
        int startMinuteIndex = startMinute;
        int endHourIndex = endHour - startHour + 1;
        int endMinuteIndex = endMinute;

        boolean flag = true;
        for (int h=startHourIndex; h<endHourIndex; h++) {
            Elements is = liList.get(h).children();
            // 需要考虑：一首、一尾、同一小时   3种情况
            int start = (h == startHourIndex ? startMinuteIndex : 0);
            int end = (h == endMinuteIndex ? endMinuteIndex : 59);
            // 遍历每个i标签
            for (int m=start; m<=end; m++) {
//                System.out.println(is.get(m).className() + '@' + is.get(m));
                if("on".equals(is.get(m).className()))
                    flag = false;
            }

        }
        return flag;
    }

    private OkHttpClient getOkHttpClient() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .cookieJar(new CookieJar() {
                    @Override
                    public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
                        cookieStore.put(httpUrl.host(), list);
                    }

                    @Override
                    public List<Cookie> loadForRequest(HttpUrl httpUrl) {
                        List<Cookie> cookies = cookieStore.get(httpUrl.host());
                        return cookies != null ? cookies : new ArrayList<Cookie>();
                    }
                })
                .connectTimeout(20000, TimeUnit.MILLISECONDS)
                .readTimeout(20000, TimeUnit.MILLISECONDS)
                .build();
        return okHttpClient;
    }

}
